package gui;

import firing.FiringTree;
import game.GameBoard;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.Timer;
import javax.swing.WindowConstants;

public class GameGui {

    public static void main(String[] args) {
	new GameGui();
    }

    public GameGui() {
	this(null);
    }

    public GameGui(FiringTree tree) {
	final JFrame application = new JFrame();
	application.setLayout(new BorderLayout());
	final boolean[] keyState = new boolean[222];
	final GameBoard game = new GameBoard(keyState);
	if (tree != null) {
	    game.setTree(tree);
	}
	game.setAdvancedPlayerAI(false);
	final GameView gameView = new GameView(game);
	final DebugInfo debug = new DebugInfo(game);

	gameView.setPreferredSize(new Dimension(400,600));
	debug.setPreferredSize(new Dimension(150,600));

	final Timer gameTimer = new Timer(1000 / 60, new ActionListener() {

	    @Override
	    public void actionPerformed(ActionEvent e) {
		game.update();
		gameView.repaint();
		debug.update();
		//debug.repaint();
	    }

	});
	application.addKeyListener(new KeyListener() {

	    @Override
	    public void keyPressed(KeyEvent k) {
		keyState[k.getKeyCode()] = true;

	    }

	    @Override
	    public void keyReleased(KeyEvent k) {
		keyState[k.getKeyCode()] = false;
		if (k.getKeyCode() == KeyEvent.VK_Q) {
		    if (gameTimer.isRunning()) {
			gameTimer.stop();
		    } else {
			gameTimer.start();
		    }
		}
		if (k.getKeyCode() == KeyEvent.VK_R) {
		    game.rebuildTree();
		}
		if (k.getKeyCode() == KeyEvent.VK_A){
		    game.setPlayerAutoPilot(!game.player.isAutoPilot());
		}
		if (k.getKeyCode() == KeyEvent.VK_B) {
		    game.togglePixelHitBox();
		}
		if (k.getKeyCode() == KeyEvent.VK_V){
		    game.togglePlayerAI();
		}
		if (k.getKeyCode() == KeyEvent.VK_W) {
		    game.showChainPenaltyRadius = !game.showChainPenaltyRadius;
		}
	    }

	    @Override
	    public void keyTyped(KeyEvent k) {
		if (k.getKeyCode() == KeyEvent.VK_P){ 
		    if (gameTimer.isRunning()) {
			gameTimer.stop();
		    } else {
			gameTimer.start();
		    }
		}
	    }

	});
	
	application.addWindowListener(new WindowListener() {

	    @Override
	    public void windowActivated(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	    }

	    @Override
	    public void windowClosed(WindowEvent arg0) {
		// TODO Auto-generated method stub
		gameTimer.stop();
	    }

	    @Override
	    public void windowClosing(WindowEvent arg0) {
		// TODO Auto-generated method stub
		gameTimer.stop();
	    }

	    @Override
	    public void windowDeactivated(WindowEvent arg0) {
		// Nothing
		
	    }

	    @Override
	    public void windowDeiconified(WindowEvent arg0) {
		//Nothing
		
	    }

	    @Override
	    public void windowIconified(WindowEvent arg0) {
		// Nothing
		
	    }

	    @Override
	    public void windowOpened(WindowEvent arg0) {
		//Nothing
	    }
	    
	});

	setUpMenu(application, game);
	ControlPanel control = new ControlPanel();
	application.add(gameView);
	application.add(debug, BorderLayout.EAST);
	application.add(control, BorderLayout.WEST);
	application.pack();
	application.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
	application.setVisible(true);
	gameTimer.start();
    }

    public static void setUpMenu(final JFrame app, final GameBoard game) {
	JMenuBar menu = new JMenuBar();
	final JFileChooser fc = new JFileChooser();
	fc.setCurrentDirectory(new File("MassTrees"));

	//file
	JMenu file = new JMenu("File");
	JMenuItem newTree = new JMenuItem("Rebuild Tree");
	JMenuItem save = new JMenuItem("Save Tree");
	JMenuItem load = new JMenuItem("Load Tree");
	JMenuItem exit = new JMenuItem("Exit");
	newTree.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent e) {
		game.rebuildTree();
	    }
	});

	save.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent action) {
		fc.setSelectedFile(new File("default.ftree"));
		int result = fc.showSaveDialog(app);
		if (result == JFileChooser.APPROVE_OPTION) {
		    try {
			FileOutputStream fileOut = new FileOutputStream(fc.getSelectedFile());
			ObjectOutputStream out = new ObjectOutputStream(fileOut);
			out.writeObject(game.overmind);
			out.close();
			fileOut.close();
		    } catch(IOException i) {
			i.printStackTrace();
		    }
		}
	    }
	});

	load.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent action) {
		int result = fc.showOpenDialog(app);
		if (result == JFileChooser.APPROVE_OPTION) {
		    try {
			FileInputStream fileIn = new FileInputStream(fc.getSelectedFile());
			ObjectInputStream in = new ObjectInputStream(fileIn);
			game.setTree((FiringTree) in.readObject());
			game.enemy.resetWastedEnergy();
			in.close();
			fileIn.close();
		    } catch(IOException e) {
			e.printStackTrace();
		    } catch (ClassNotFoundException e) {
			e.printStackTrace();
		    }
		}
	    }
	});

	exit.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent e) {
		System.exit(0);
	    }
	});

	file.add(newTree);
	file.add(save);
	file.add(load);
	file.add(exit);
	menu.add(file);
	app.setJMenuBar(menu);
    }

}
